﻿using BoldBrick.Core.Logging;
using BoldBrick.SharePoint.CommonControls.DataObjects.Base;
using Microsoft.SharePoint;

namespace BoldBrick.SharePoint.CommonControls.Extensions
{
	/// <summary>
	/// Extension class for <see cref="SPField"/> objects
	/// </summary>
	public static class SPFieldEx
	{
		private static readonly ILogger log = Logger.GetLogger(typeof(SPFieldEx));

		/// <summary>
		/// Sets properties of field from <see cref="ListColumn"/> object
		/// </summary>
		/// <param name="field">Field to set</param>
		/// <param name="listColumn"><see cref="ListColumn"/> object with properties</param>
		/// <param name="language">Language identifier</param>
		public static void SetFieldProperties(this SPField field, ListColumn listColumn, uint language)
		{
			if (listColumn.ShowInDisplayForm.HasValue)
			{
				LogProperty("ShowInDisplayForm", listColumn, listColumn.ShowInDisplayForm);
				field.ShowInDisplayForm = listColumn.ShowInDisplayForm;
			}

			if (listColumn.ShowInEditForm.HasValue)
			{
				LogProperty("ShowInEditForm", listColumn, listColumn.ShowInEditForm);
				field.ShowInEditForm = listColumn.ShowInEditForm;
			}

			if (listColumn.ShowInNewForm.HasValue)
			{
				LogProperty("ShowInNewForm", listColumn, listColumn.ShowInNewForm);
				field.ShowInNewForm = listColumn.ShowInNewForm;
			}

			if (listColumn.Required.HasValue)
			{
				LogProperty("Required", listColumn, listColumn.Required);
				field.Required = listColumn.Required.Value;
			}

			if (listColumn.Hidden.HasValue)
			{
				LogProperty("Hidden", listColumn, listColumn.Hidden);
				field.Hidden = listColumn.Hidden.Value;
			}

			foreach (ListColumnProperty columnProperty in listColumn.Properties)
			{
				LogProperty(columnProperty.Name, listColumn, columnProperty.Value);
				field.SetCustomProperty(columnProperty.Name, columnProperty.Value);
			}
			string displayName = listColumn.GetDisplayName(language);
			LogProperty("Title", listColumn, displayName);
			field.Title = displayName;

			if (!string.IsNullOrEmpty(listColumn.Description))
			{
				LogProperty("Description", listColumn, listColumn.Description);
				field.Description = listColumn.Description;
			}
		}

		/// <summary>
		/// Gets typed custom property of the field
		/// </summary>
		/// <typeparam name="TClass">Type of the custom property value</typeparam>
		/// <param name="field">The field</param>
		/// <param name="propertyName">Name of the property</param>
		/// <param name="defaultValue">Default value of the property if property is not set</param>
		/// <returns>Returns typed custom property of the field if property is set, otherwise returns <paramref name="defaultValue"/></returns>
		public static TClass GetCustomProperty<TClass>(this SPField field, string propertyName, TClass defaultValue)
		{
			object propertyValue = field.GetCustomProperty(propertyName);
			if (propertyValue == null)
				return defaultValue;

			return (TClass) propertyValue;
		}

		private static void LogProperty(string propertyName, ListColumn listColumn, object value)
		{
			log.Write(LogLevel.Info, "Set '{0}' property for '{1}' field to value = '{2}'.", propertyName, listColumn, value);
		}
	}
}
